package basic.courseLearn14.bitOperation;

import org.junit.Test;

//使用位运算实现加减乘除
public class BasicOperation {

    @Test
    public void test_add(){
        System.out.println("0+1= "+add(0,1));
        System.out.println("1+2= "+add(1, 2));
        System.out.println("10+5= "+add(10, 5));
        System.out.println("100+50= "+add(100, 50));
    }

    @Test
    public void test_subtract(){
        System.out.println("0-1= "+subtract(0,1));
        System.out.println("1-2= "+subtract(1, 2));
        System.out.println("10-5= "+subtract(10, 5));
        System.out.println("100-50= "+subtract(100, 50));
    }

    @Test
    public void test_multiply(){
        System.out.println("0*1= "+multiply(0,1));
        System.out.println("7*5= "+multiply(7, 5));
        System.out.println("10*5= "+multiply(10, 5));
        System.out.println("100*50= "+multiply(100, 50));
    }

    @Test
    public void test_divide(){
        System.out.println("0/1= "+divide(0,1));
        System.out.println("7/5= "+divide(7, 5));
        System.out.println("10/5= "+divide(10, 5));
        System.out.println("100/50= "+divide(100, 50));
    }


    //加法
    public int add(int a, int b) {
        int basicInfo = a ^ b; //无进位相加
        int carryInfo = (a & b) << 1; //进位信息
        while(carryInfo != 0){
            int temp = basicInfo ^ carryInfo; //进位相加
            carryInfo = (basicInfo & carryInfo) << 1; //进位信息
            basicInfo = temp; //更新基本信息
        }
        return basicInfo;
    }

    //减法
    public int subtract(int a, int b) {
        return add(a, reverse(b));
    }

    //取反，即取反符号
    public int reverse(int a) {
        return ~a+1;
    }

    //乘法
    public int multiply(int a, int b) {
        int result = 0;
        while(b != 0){
            if ((b & 1)==1){
                result = add(result, a);
            }
            a = a << 1;
            b = b >>> 1;
        }
        return result;
    }

    //除法
    public int divide(int a, int b) {
        int result = 0;
        int temp_a = a;
        while(temp_a >= b){
            //使得b左移，找到小于a的最大情况，同时记录高位
            int count = 0;
            int temp_b = b;
            while(temp_a >= temp_b){
                temp_b = temp_b << 1;
                count++;
            }
            count--;
            temp_b = temp_b >>1;
            result += 1<<count;
            temp_a = temp_a - temp_b;
        }
        return result;
    }





}
